namespace SilverSea.Sockets
{
    using System;
    using System.IO;
    using System.Net;
    using System.Net.Sockets;
    using System.Text;
    using System.Threading;

    public class SocketClient
    {
        private AsyncCallback asyncCallback_0;
        private bool bool_0;
        private int int_0;
        private Socket socket_0;
        private string string_0;

        public event DataReceivedInByteArrayEventHandler DataReceivedInByteArrayEvent;

        public event DataReceivedInStringEventHandler DataReceivedInStringEvent;

        public event ServerConnectedEventHandler ServerConnected;

        public event SocketErrorEventHandler SocketErrorEvent;

        public SocketClient()
        {
            this.string_0 = "127.0.0.1";
            this.int_0 = 0xc350;
        }

        public SocketClient(string serverIP, int serverPort)
        {
            this.string_0 = "127.0.0.1";
            this.int_0 = 0xc350;
            this.string_0 = serverIP;
            this.int_0 = serverPort;
        }

        public bool Connect()
        {
            try
            {
                this.socket_0 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(this.string_0), this.int_0);
                this.socket_0.Connect(remoteEP);
                if (this.socket_0.Connected)
                {
                    if (this.ServerConnected != null)
                    {
                        this.ServerConnected(this.string_0, this.int_0);
                    }
                    this.bool_0 = true;
                    this.method_0();
                    return true;
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Connection failed, is the server running?\n" + exception.Message);
                }
            }
            catch (Exception exception2)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while connect to server." + exception2.Message);
                }
            }
            return false;
        }

        public bool Disconnect()
        {
            try
            {
                this.bool_0 = false;
                if (this.socket_0 != null)
                {
                    this.socket_0.Close();
                    this.socket_0 = null;
                }
                return true;
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while disconnect to server." + exception.Message);
                }
            }
            return false;
        }

        private void method_0()
        {
            try
            {
                if (this.asyncCallback_0 == null)
                {
                    this.asyncCallback_0 = new AsyncCallback(this.method_1);
                }
                SocketPacket state = new SocketPacket {
                    clientSocket = this.socket_0
                };
                this.socket_0.BeginReceive(state.dataBuffer, 0, state.dataBuffer.Length, SocketFlags.None, this.asyncCallback_0, state);
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while wait to data from server." + exception.Message);
                }
            }
        }

        private void method_1(IAsyncResult iasyncResult_0)
        {
            try
            {
                SocketPacket asyncState = (SocketPacket) iasyncResult_0.AsyncState;
                if ((asyncState.clientSocket != null) && asyncState.clientSocket.Connected)
                {
                    int dataReceivedLength = asyncState.clientSocket.EndReceive(iasyncResult_0);
                    if (dataReceivedLength > 0)
                    {
                        string dataReceivedString = Encoding.UTF8.GetString(asyncState.dataBuffer);
                        if (this.DataReceivedInStringEvent != null)
                        {
                            this.DataReceivedInStringEvent(dataReceivedString);
                        }
                        if (this.DataReceivedInByteArrayEvent != null)
                        {
                            this.DataReceivedInByteArrayEvent(asyncState.dataBuffer, dataReceivedLength);
                        }
                    }
                    this.method_0();
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while receiving data from server." + exception.Message);
                }
            }
        }

        public void SaveFile(string receivedPath, byte[] clientData, int receivedBytesLen)
        {
            try
            {
                int count = BitConverter.ToInt32(clientData, 0);
                string str = Encoding.UTF8.GetString(clientData, 4, count);
                BinaryWriter writer = new BinaryWriter(System.IO.File.Open(receivedPath + "/" + str, FileMode.Append));
                writer.Write(clientData, 4 + count, (receivedBytesLen - 4) - count);
                writer.Close();
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while saving file." + exception.Message);
                }
            }
        }

        public void SendFile(string fileName)
        {
            try
            {
                string str = string.Empty;
                fileName = fileName.Replace(@"\", "/");
                while (fileName.IndexOf("/") > -1)
                {
                    str = str + fileName.Substring(0, fileName.IndexOf("/") + 1);
                    fileName = fileName.Substring(fileName.IndexOf("/") + 1);
                }
                byte[] bytes = Encoding.UTF8.GetBytes(fileName);
                if (bytes.Length <= 0xd4800)
                {
                    byte[] buffer2 = System.IO.File.ReadAllBytes(str + fileName);
                    byte[] array = new byte[(4 + bytes.Length) + buffer2.Length];
                    BitConverter.GetBytes(bytes.Length).CopyTo(array, 0);
                    bytes.CopyTo(array, 4);
                    buffer2.CopyTo(array, (int) (4 + bytes.Length));
                    this.SendMessage(array);
                }
            }
            catch (Exception exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while sending file to server." + exception.Message);
                }
            }
        }

        public void SendMessage(string message)
        {
            try
            {
                byte[] bytes = Encoding.UTF8.GetBytes(message);
                if ((this.socket_0 != null) && this.socket_0.Connected)
                {
                    this.socket_0.Send(bytes);
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while sending data to server." + exception.Message);
                }
            }
        }

        public void SendMessage(byte[] message)
        {
            try
            {
                if ((this.socket_0 != null) && this.socket_0.Connected)
                {
                    this.socket_0.Send(message);
                }
            }
            catch (SocketException exception)
            {
                if (this.SocketErrorEvent != null)
                {
                    this.SocketErrorEvent("Error while sending data to server." + exception.Message);
                }
            }
        }

        public bool IsRunning
        {
            get
            {
                return this.bool_0;
            }
            set
            {
                this.bool_0 = value;
            }
        }

        public string ServerIP
        {
            get
            {
                return this.string_0;
            }
            set
            {
                this.string_0 = value;
            }
        }

        public int ServerPort
        {
            get
            {
                return this.int_0;
            }
            set
            {
                this.int_0 = value;
            }
        }
    }
}

